package com.ruoyi.game.core.card;

import com.ruoyi.game.core.GameRoundPos;
import com.ruoyi.game.core.GameSetCore;
import com.ruoyi.game.core.GameSetPos;
import com.ruoyi.game.core.GameRoundCore;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.game.core.card.BasePoker.toCardString;

/**
 * 连对牌型出牌策略
 */
@Slf4j
public class LianDuiCardTypeImpl extends BaseCardType {

    @Override
    public String getName() {
        return "连对";
    }

    @Override
    public List<Integer> firstAutoOut(GameSetPos pos) {
        GameSetCore set = pos.getGameSet();
        if (set == null) {
            log.warn("[LianDuiCardType] 玩家 {} 无法首出，未找到 GameSetCore", pos.getPlayerId());
            return Collections.emptyList();
        }

        int zhuColor = set.getLiangZhuInfo().getZhuColor();
        int zhuValue = set.getZhuValue();

        // 直接使用所有手牌，找出最长的连对（已自动区分主副）
        List<Integer> all = pos.getHandCards();
        List<Integer> result = findLianDui(all, zhuColor, zhuValue, 0, -1);

        if (!result.isEmpty()) {
            log.info("[LianDuiCardType] 玩家 {} 首出找到连对：{}", pos.getPlayerId(),
                    result.stream().map(BasePoker::getCardDescription).collect(Collectors.joining(", ")));
        } else {
            log.warn("[LianDuiCardType] 玩家 {} 首出未找到连对", pos.getPlayerId());
        }

        return result;
    }


    @Override
    public List<Integer> followAutoOut(GameSetPos pos, GameRoundCore round) {
        if (round == null) {
            log.warn("[LianDuiCardType] 玩家 {} 跟牌失败，当前回合为 null", pos.getPlayerId());
            return Collections.emptyList();
        }

        GameSetCore set = round.getRoomSet();
        int zhuColor = set.getLiangZhuInfo().getZhuColor();
        int zhuValue = set.getZhuValue();
        int firstOutColor = BasePoker.getCardColor(round.getFirstOutCards().get(0));

        List<Integer> sameColor = getFollowableCards(pos, round);
        log.info("[LianDuiCardType] 玩家 {} 跟牌，手牌同色牌：{}", pos.getPlayerId(),toCardString(sameColor));

        int targetSize = round.getFirstOutCards().size();
        log.info("[LianDuiCardType] 玩家 {} 跟牌，目标大小：{}", pos.getPlayerId(), targetSize);

        List<Integer> result = findLianDui(sameColor, zhuColor, zhuValue, targetSize, firstOutColor);
        if (!result.isEmpty()) {
            log.info("[LianDuiCardType] 玩家 {} 跟牌成功（同花色连对）：{}", pos.getPlayerId(),
                    result.stream().map(BasePoker::getCardDescription).collect(Collectors.joining(", ")));
            return result;
        }

        List<Integer> all = pos.getHandCards();
        result = findLianDui(all, zhuColor, zhuValue, targetSize, firstOutColor);
        if (!result.isEmpty()) {
            log.info("[LianDuiCardType] 玩家 {} 跟牌使用任意连对：{}", pos.getPlayerId(),
                    result.stream().map(BasePoker::getCardDescription).collect(Collectors.joining(", ")));
        } else {
            log.warn("[LianDuiCardType] 玩家 {} 跟牌失败，未找到合适连对", pos.getPlayerId());
        }
        return result;
    }

    /**
     * 获取某花色的手牌
     */
    private List<Integer> getCardsByColor(GameSetPos pos, int color) {
        return pos.getHandCards().stream()
                .filter(c -> BasePoker.getCardColor(c) == color)
                .collect(Collectors.toList());
    }

    /**
     * 查找连对（任意长度）
     */
    private List<Integer> findLianDui(List<Integer> cards, int zhuColor, int zhuValue, int targetSize, int targetColor) {
        List<List<Integer>> lianDuis = lianDuiList(cards, zhuColor, zhuValue, targetColor);
        lianDuis.sort((a, b) -> {
            if (a.size() != b.size()) return Integer.compare(b.size(), a.size());
            return Integer.compare(BasePoker.getCardValueEx(a.get(0)), BasePoker.getCardValueEx(b.get(0)));
        });

        for (List<Integer> lianDui : lianDuis) {
            if (targetSize == 0 || lianDui.size() == targetSize) {
                return lianDui;
            }
        }
        return Collections.emptyList();
    }
}
